#!C:/Users/xiedaolin/AppData/Local/Microsoft/WindowsApps/python.exe
import pyautogui
import fire
import time
from threading import Timer
import random



# **********使用Python的日志功能**********begin
import logging
logFileName = "log/GoTAuto{}.log".format(time.strftime("%Y%m%d"))
logger = logging.getLogger("GOTAuto")
handlerConsole = logging.StreamHandler()
handlerFile = logging.FileHandler(filename=logFileName)
logger.setLevel(logging.DEBUG)
handlerConsole.setLevel(logging.INFO)
handlerFile.setLevel(logging.DEBUG)
formatter = logging.Formatter(
    "[%(asctime)s %(name)s %(levelname)s]>>> %(message)s")
handlerConsole.setFormatter(formatter)
handlerFile.setFormatter(formatter)
logger.addHandler(handlerConsole)
logger.addHandler(handlerFile)
# **********使用Python的日志功能**********end

# time.sleep(1)
# 截图派出军队图标上的数字
# g.screenshot('scrShot\\four.png', region=(55,726,10,16))

# 快捷键
# [Q]======>> 神秘宝箱
# [W]======>> 心树
# [E]======>> 铁匠铺
# [Y]======>> 医院
# [I]======>> 背包
# [P]======>> 邮件
# [D]======>> 巨龙
# [F]======>> 通讯录
# [H]======>> 指挥官
# [Z]======>> 任务
# [B]======>> 七神圣堂
# [S/R]======>> 关闭窗口，但是有什么区别不太清楚 2020年5月19日
# [M]======>> 世界/主城切换

# 地图模式 country | world
G_MAP_MODE = "country"

pyautogui.PAUSE = 1

# 全局鼠标移动的时间
DURATION = 1
ARMY_LIMIT = 5  # 行军队列上限数量
SCREEN_MID_X, SCREEN_MID_Y = 840, 525  # 屏幕中间
SCREEN_WIDTH, SCREEN_HEIGHT = pyautogui.size()
SPOILS_COUNT = 0  # 战利品个数
TOTAL_TROOPS = 182  # 总兵力 单位K
STATIONED = 0  # 在营兵力
ON_MARCH = 0  # 行军兵力
STOP_BATTLE_ON = True  # 是否要常年开启停战协议


def trainingGrounds(model=1):
    training_x, training_y = 530, 576
    training_close_x, training_close_y = 1347, 191
    training_model1_x, training_model1_y = 620,  538
    training_model2_x, training_model2_y = 1076, 538
    model2_btn_start_x, model2_btn_start_y = 1315, 949
    model2_btn_close_x, model2_btn_close_y = 1644, 64
    war_btn_start_x, war_btn_start_y = 1330, 886
    war_btn_quit_x, war_btn_quit_y = 979, 743
    pyautogui.click(training_x, training_y, duration=DURATION)

    if model == 1:
        pass
    else:
        for i in range(10):
            pyautogui.click(training_model2_x, training_model2_y, duration=1)
            pyautogui.click(model2_btn_start_x, model2_btn_start_y, duration=1)
            pyautogui.click(war_btn_start_x, war_btn_start_y, duration=1)
            time.sleep(5)
            pyautogui.click(war_btn_quit_x, war_btn_quit_y, duration=1)
            pyautogui.click(model2_btn_close_x, model2_btn_close_y, duration=1)
            logger.info("游兵远征关卡第{}次结束。".format(i+1))

    # 关闭总窗口
    pyautogui.click(training_close_x, training_close_y, duration=DURATION)


def getArmyCount():
    # 检查派出去的几只军队
    regionChecked = (10, 700, 80, 80)
    count = 0
    for i, f in enumerate(('scrShot\\one.png', 'scrShot\\two.png', 'scrShot\\three.png', 'scrShot\\four.png', 'scrShot\\five.png')):
        im = pyautogui.locateOnScreen(f, confidence=0.9, region=regionChecked)
        if im:
            count = i + 1
            break
    return count


def auctionSpoils():
    # 拍卖战利品********
    logger.info("检查商会是否有战利品可以进行拍卖。")
    # Merchant Guild 商人工会 商会坐标
    merchantGuildX, merchantGuildY = 812, 596
    merchantGuildWndCloseX, merchantGuildWndCloseY = 1342, 190
    pyautogui.click(merchantGuildX, merchantGuildY, duration=DURATION)

    # 点击领取按钮，不管有无都点击下，无影响
    btnClaimX, btnClaimY = 668, 848
    pyautogui.click(btnClaimX, btnClaimY, duration=DURATION)

    # 检查是否还有剩余的战利品未拍卖
    searchRegion = (1017, 218, 330, 650)
    offsetX, offsetY = 80, 60
    findPosList = list(pyautogui.locateAllOnScreen(
        'scrShot\\spoilsBox.png', region=searchRegion))

    # 找到多个的话就拍卖第一个
    global SPOILS_COUNT
    SPOILS_COUNT = len(findPosList)
    if SPOILS_COUNT < 1:
        logger.info("无战利品可以进行拍卖。")
    else:
        logger.info("目前发现有{}个战利品可以进行拍卖。".format(SPOILS_COUNT))
        # 找到多个的话就拍卖第一个
        pos = findPosList[0]
        pyautogui.click(pos.left + offsetX, pos.top +
                        offsetY, duration=DURATION)
        # 战利品拍卖确认窗口
        # spoilsWndCloseX, spoilsWndCloseY = 1082, 193
        btnAuctionX, btnAuctionY = 963, 825  # 拍卖按钮
        pyautogui.click(btnAuctionX, btnAuctionY, duration=DURATION)

    # Close the window
    pyautogui.click(merchantGuildWndCloseX,
                    merchantGuildWndCloseY, duration=DURATION)


def rallyAttack():
    # 集结攻击 叛军营地/巨龙巢穴
    # Rebel Camp  叛军营地
    # 检查有叛军营地的集结召集
    findPos = pyautogui.locateCenterOnScreen("scrShot\\rallyFlag.png")
    # 点击召集的旗帜
    if findPos:
        logger.info("有集结攻击着急旗帜。")
        pyautogui.click(findPos.x, findPos.y, duration=DURATION)
        searchRegion = (1080, 250, 400, 600)
        findPos = pyautogui.locateCenterOnScreen(
            "scrShot\\rebelCamp.png",  confidence=0.9, region=searchRegion)
        if findPos:
            # 弹出集结窗口
            pyautogui.click(findPos.x, findPos.y, duration=DURATION)
            # 参与集结
            btnJoinRallyX, btnJoinRallyY = 834, 821
            pyautogui.click(btnJoinRallyX, btnJoinRallyY, duration=DURATION)
            # 确认参与集结 ，大概意思就是派出去的兵要听对方的了，不能调动。
            btnConfirmYesX, btnConfirmYesY = 965, 655
            pyautogui.click(btnConfirmYesX, btnConfirmYesY, duration=DURATION)

            # 弹出派兵的窗口
            btnAttackX, btnAttackY = 1136, 797
            btnAutoSelectDragonX, btnAutoSelectDragonY = 644, 393  # 自动选择 龙

            btnClearSelectionX, btnClearSelectionY = 1153, 744  # 清除选择
            pyautogui.click(btnClearSelectionX,
                            btnClearSelectionY, duration=DURATION)
            pyautogui.click(btnClearSelectionX,
                            btnClearSelectionY, duration=DURATION)

            pyautogui.click(btnAutoSelectDragonX,
                            btnAutoSelectDragonY, duration=DURATION)
            pyautogui.click(btnAttackX, btnAttackY, duration=DURATION)

    else:
        logger.info("无集结攻击旗帜。")

    # 匹配叛军营地列表，g.locateOnScreen('d:\\temp\\rebelCamp.png', region=(928,258,500,600))
    # 点击
    # 开始派兵
    rallyAttackCloseX, rallyAttackCloseY = 1330, 218


def weirwoodTree():
    # 心树  weirwood
    pass


def checkHospital():
    """检查医院是否有伤兵，点击治疗"""
    logger.info("检查医院是否有伤兵，点击治疗")
    pyautogui.press("Y")

    btnTreatX, btnTreatY = 1267, 823
    pyautogui.click(btnTreatX, btnTreatY, duration=DURATION)

    btnConfirmX, btnConfirmY = 964, 825
    pyautogui.click(btnConfirmX, btnConfirmY, duration=DURATION)

    closeActiveWindows()


def setWndFocus():
    # 窗口获得焦点
    mainwnd_x = 1500
    mainwnd_y = 300
    pyautogui.click(mainwnd_x, mainwnd_y, clicks=2,
                    interval=0.5, button="right")

    # 保证窗口界面是最远处视图
    pyautogui.scroll(-20)
    pyautogui.scroll(-20)
    pyautogui.scroll(-20)
    # pyautogui.click(mainwnd_x, mainwnd_y)


def checkChest():
    # 检查神秘宝箱是否可以领取 宝箱快捷键 Q
    # 神秘宝箱弹出窗口后 领取或者确认按钮的位置
    box_btn_get_x, box_btn_get_y = 829, 672

    logger.info("检查神秘宝箱是否可以领取。")
    pyautogui.press("Q")  # 使用快捷键，可以在任何地图模式

    searchRegion = (625, 580, 425, 200)
    findPos = pyautogui.locateCenterOnScreen(
        "scrShot\\claim.png", confidence=0.9, region=searchRegion)

    # 有红点表示神秘宝箱可以领取
    if findPos:
        # 点击宝箱==》点击确认/领取
        logger.info("领取神秘宝箱一次。")
        pyautogui.click(findPos.x, findPos.y, duration=DURATION)
    else:
        logger.info("神秘宝箱暂时还不能领取。")
        pyautogui.click(box_btn_get_x, box_btn_get_y, duration=DURATION)

    # # 检查神秘宝箱
    # searchRegion = (1300, 70, 80, 80)
    # findPos = pyautogui.locateOnScreen(
    #     "scrShot\\reddot.png", confidence=0.9, region=searchRegion)
    # # 有红点表示神秘宝箱可以领取
    # if findPos:
    #     # 点击宝箱==》点击确认/领取 内政地图
    #     logger.info("神秘宝箱已经可以领取。")
    #     pyautogui.press("Q") #使用快捷键，可以在任何地图模式
    #     # pyautogui.click(box_pos_x, box_pos_y, duration=DURATION)
    #     pyautogui.click(box_btn_get_x, box_btn_get_y, duration=DURATION)
    # else:
    #     logger.info("神秘宝箱暂时还不能领取。")


def getMapMode():
    '''# 检测当前是什么地图模式【country, world】'''
    currentMapMode = ""
    # 校验当前的地图模式
    searchRegion = (0, 530, 80, 250)
    # 判断是否内政模式
    findCountry = pyautogui.locateOnScreen(
        'scrShot\\map_country.png', confidence=0.9, region=searchRegion)
    # 判断是否世界模式
    findWorld = pyautogui.locateOnScreen(
        'scrShot\\map_world.png', confidence=0.9, region=searchRegion)

    if findCountry and not findWorld:
        currentMapMode = "country"
    elif findWorld and not findCountry:
        currentMapMode = "world"
    else:
        currentMapMode = "nothing"
    return currentMapMode


def restartGame():
    '''# 重新刷新游戏'''
    btnRefreshX, btnRefreshY = 259, 12
    pyautogui.click(btnRefreshX, btnRefreshY, duration=DURATION)
    time.sleep(20)

    pyautogui.click(245, 80, clicks=8, interval=1)
    # 保证窗口界面是最远处视图
    pyautogui.scroll(-20)
    pyautogui.scroll(-20)
    pyautogui.scroll(-20)


def switchMapMode(mapMode='country'):
    '''# 切换指定的地图模式'''
    logger.info("开始进行地图模式切换：==> {}".format(mapMode))
    curMapMode = getMapMode()
    if curMapMode == mapMode:
        logger.info("当前的地图模式就是{}，无需切换".format(curMapMode))
        return True
    else:
        pyautogui.press("m")
        time.sleep(5)  # 等待地图切换
        # 判断切换地图是否加载完毕，给100秒的时间
        for i in range(30):
            time.sleep(2)
            if i == 29:
                pyautogui.screenshot("screenshot-{}.png".format(time.strftime("%Y%m%d%H%M%S")))
                restartGame()  # 终极大法，重启游戏
                pyautogui.screenshot("screenshot-{}.png".format(time.strftime("%Y%m%d%H%M%S")))
            curMapMode = getMapMode()
            logger.info("切换地图模式[==>{}]切换中。。。。。。等待[{}]".format(mapMode, i))
            # 如果8秒了还未切换过来，则用鼠标点击的方法
            if (i+1) % 4 == 0:
                pyautogui.click(1628, 948, duration=DURATION)
            if curMapMode == mapMode:
                logger.info("地图切换成功，切换成功的地图模式：{}".format(mapMode))
                # 保证窗口界面是最远处视图
                pyautogui.scroll(-20)
                pyautogui.scroll(-20)
                pyautogui.scroll(-20)
                return True
    pyautogui.screenshot("screenshot-{}.png".format(time.strftime("%Y%m%d%H%M%S")))
    logger.info("切换地图模式[{}]失败，时间超时。".format(mapMode))
    return False


def checkTavernBonus():
    '''
    检查酒馆是否有可领取的奖励资源 酒馆 tavern  Bonus奖励
    '''
    # 检查是否可以领取
    searchRegion = (890, 400, 100, 100)
    findPos = pyautogui.locateOnScreen(
        'scrShot\\marksign.png', confidence=0.9, region=searchRegion)
    if not findPos:
        logger.info("酒馆奖励资源暂时还不能领取。")
        return

    # 酒馆
    pub_x, pub_y = 909, 484
    pub_close_x, pub_close_y = 1340, 199
    # 打开酒馆收益界面
    pyautogui.click(pub_x, pub_y, duration=DURATION)

    searchRegion = (1120, 290, 200, 300)
    findPos = pyautogui.locateAllOnScreen(
        "scrShot\\pubclaim.png", confidence=0.9, region=searchRegion)
    # 匹配到表示可以领取
    for pos in findPos:
        logger.info("酒馆收益已经可以领取,点击按钮坐标x={},y={}。".format(pos.left, pos.top))
        pyautogui.click(pos.left, pos.top, duration=DURATION)

    pyautogui.click(pub_close_x, pub_close_y, duration=DURATION)


def doTimerMinutes(amount=5.0):
    '''
    定时执行任务
    args:
        amount 定时执行多少分钟
    '''
  
    # if getArmyCount() < ARMY_LIMIT:
    #     if switchMapMode("world"):
    #         searchResources()
    # else:
    #     logger.info("资源采集军队已经派出去上限{}支，暂无军队可派遣。".format(ARMY_LIMIT))

    # 执行特定任务
    logger.info("{}分钟定时任务执行【开始】。".format(amount))
    setWndFocus()  #让窗口保持焦点
    switchMapMode("country") #地图切换为内政模式
    checkChest()      #检查宝箱
    helpAlliance()     #联盟帮助
    claimAllianceGift() #联盟礼物
    checkTavernBonus() #检查酒馆奖励
    auctionSpoils()  # 战利品
    checkMerchantShip() #检查商船
    checkQuest()  #检查任务队列
    #自动采集矿场资源
    switchMapMode("world")
    gatherAndClearFromBookmark()
    claimResourceAutoRand()
    logger.info("{}分钟定时任务执行【结束】。".format(amount))
    #计划下次的循环计划
    Timer(amount * 60, doTimerMinutes, [amount]).start()



def closeActiveWindows():
    logger.info("利用快捷键【S】关闭当前所有活动窗口。")
    pyautogui.press("S")

    # # 关闭所有带 X 图标的窗口
    # searchRegion = (SCREEN_MID_X, 0, 840, 500)
    # while True:
    #     findPosCenter = pyautogui.locateCenterOnScreen(
    #         "scrShot\\buttonClose.png", confidence=0.9, region=searchRegion)
    #     if findPosCenter:
    #         logger.info("找到窗口进行关闭，窗口坐标位置x={},y={}".format(
    #             findPosCenter.x, findPosCenter.y))
    #         pyautogui.click(findPosCenter.x, findPosCenter.y,
    #                         duration=DURATION)

    #     findPosCenter2 = pyautogui.locateCenterOnScreen(
    #         "scrShot\\buttonClose2.png", confidence=0.9, region=searchRegion)
    #     if findPosCenter2:
    #         logger.info("找到窗口进行关闭，窗口坐标位置x={},y={}".format(
    #             findPosCenter2.x, findPosCenter2.y))
    #         pyautogui.click(findPosCenter2.x, findPosCenter2.y,
    #                         duration=DURATION)

    #     if not findPosCenter and not findPosCenter2:
    #         logger.info("未找到有活动窗口。")
    #         break


def checkMerchantShip():
    '''# 检查商船 Merchant Ship'''
    logger.info("开始检查商船是否有可以购买物品。")
    # 商船
    shipX, shipY = 1303, 487
    # shipWindowCloseX, shipWindowCloseY = 1343, 190
    regionChecked = (335, 536, 1000, 350)
    pyautogui.click(shipX, shipY, duration=DURATION)
    time.sleep(2)  # 太快了，匹配不到图片
    for pos in pyautogui.locateAllOnScreen('scrShot\\boat_buy_can.png', confidence=0.9, region=regionChecked):
        logger.info("找到矿物资源足够支付且可购买的物品。")
        pyautogui.moveTo(pos.left, pos.top)
        pyautogui.click(pos.left, pos.top, duration=DURATION)

    for pos in pyautogui.locateAllOnScreen('scrShot\\boat_buy_not.png', confidence=0.9, region=regionChecked):
        logger.info("找到可购买的物品，但是矿物资源不足，需要资源道具。")
        pyautogui.moveTo(pos.left, pos.top, duration=DURATION)
        not_engouh_OK_x, not_engouh_OK_y = 960, 653
        one_key_x, one_key_y = 997, 331
        res_apply_x, res_apply_y = 836, 813
        pyautogui.click(pos.left, pos.top)
        pyautogui.click(not_engouh_OK_x, not_engouh_OK_y, duration=DURATION)
        pyautogui.click(one_key_x, one_key_y, duration=DURATION)
        pyautogui.click(res_apply_x, res_apply_y, duration=DURATION)
        pyautogui.click(pos.left, pos.top, duration=DURATION)

    # 关闭商船购买界面
    # pyautogui.click(shipWindowCloseX, shipWindowCloseY, duration=DURATION)
    closeActiveWindows()


def helpAlliance():
    # 联盟帮助点击
    # #找到联盟帮助的图标
    searchRegion = (1000, 750, 250, 120)
    findpos = pyautogui.locateCenterOnScreen(
        'scrShot\\alliancehelp.png', confidence=0.9, region=searchRegion)
    if findpos:
        logger.info("找到联盟帮助，点击帮助。")
        findposX, findposY = findpos
        pyautogui.click(findposX, findposY, duration=DURATION)
    else:
        logger.info("未找到联盟帮助。")


def claimAllianceGift():
    # 收集联盟的礼物
    alliance_close_x, alliance_close_y = 1343, 190
    # 联盟快捷键
    pyautogui.press('c')
    giftWnd_x, giftWnd_y = 920, 620
    pyautogui.click(giftWnd_x, giftWnd_y, duration=DURATION)

    gift_all_x, gift_all_y = 1254, 397
    gift_del_x, gift_del_y = 1296, 398
    pyautogui.click(gift_all_x, gift_all_y, duration=DURATION)
    pyautogui.click(gift_del_x, gift_del_y, duration=DURATION)

    pyautogui.click(alliance_close_x, alliance_close_y, duration=DURATION)
    pyautogui.click(alliance_close_x, alliance_close_y, duration=DURATION)


def checkQuest():
    # 检查任务列表
    # 检查任务列表 红点不会自动出现，需要手工点击刷新出来
    logger.info("开始检查任务列表。。。。。。")
    # searchRegion=(1263,924, 80, 80)
    # offsetX,offsetY= -20, 20
    # findPos = pyautogui.locateOnScreen("scrShot\\reddot.png", confidence=0.9, region=searchRegion)

    # 打开任务列表窗口
    # pyautogui.click(findPos.left + offsetX, findPos.top + offsetY, duration=DURATION)
    pyautogui.press("z")

    # 联盟任务列表
    logger.info("点击联盟任务列表。")
    allianceTask_x, allianceTask_y = 954, 219
    allianceTask_claim_x, allianceTask_claim_y = 1243, 305
    pyautogui.click(allianceTask_x, allianceTask_y, duration=DURATION)
    pyautogui.click(allianceTask_claim_x,
                    allianceTask_claim_y, duration=DURATION)

    # VIP任务列表
    logger.info("检查VIP任务列表")
    vipTask_x, vipTask_y = 1183, 217
    pyautogui.click(vipTask_x, vipTask_y, duration=DURATION)
    # 搜索哪个宝箱未打开 confidence=0.9,
    searchRegion = (460, 430, 800, 400)
    findpos = pyautogui.locateCenterOnScreen(
        'scrShot\\vipbox.png',  region=searchRegion)
    if findpos:
        logger.info("已找到未开的VIP宝箱。")
        findposX, findposY = findpos
        pyautogui.click(findposX, findposY, duration=DURATION)
    # 关闭任务列表窗口
    taskWindow_close_x, taskWindow_close_y = 1342, 220
    pyautogui.click(taskWindow_close_x, taskWindow_close_y, duration=DURATION)


def claimSalary():
    '''# 领取俸禄'''
    NobilityWndX, NobilityWndY = 405, 127
    pyautogui.click(NobilityWndX, NobilityWndY, duration=DURATION)

    btnClaimX, btnClaimY = 1177, 321
    pyautogui.click(btnClaimX, btnClaimY, duration=DURATION)

    closeActiveWindows()


def getVIPPoints():
    '''# 领取VIP'''
    logger.info("领取VIP每日积分，每日免费宝箱。")
    VIPX, VIPY = 486, 126
    pyautogui.click(VIPX, VIPY, duration=DURATION)

    VIPFreeChestX, VIPFreeChestY = 1268, 308
    pyautogui.click(VIPFreeChestX, VIPFreeChestY, duration=DURATION)

    VIPDailyChestX, VIPDailyChestY = 1193, 607
    pyautogui.click(VIPDailyChestX, VIPDailyChestY, duration=DURATION)

    closeActiveWindows()


def attackRebel():
    '''
    # 精英叛军 Elite
    '''
    # 搜索叛军，设定级别

    # 判断是否精英叛军

    # 判断现在剩余兵力多少？是否足够

    # 派兵攻打精英叛军，判断是否派军成功

    # 需要判断是否已经回营，这样继续派兵下一波

    pass


def stopBattle():
    """使用停战协议，判断失效了就立马开启防护罩"""
    if STOP_BATTLE_ON:
        logger.info("开始检查城堡的保护罩状态。。。")
    else:
        logger.info("系统设置不需要开启保护罩，退出检查。")
        return

    pyautogui.press("B")

    btnStopBattleX, btnStopBattleY = 1048, 471

    searchRegion = (340, 250, 950, 130)
    findPosCenter = pyautogui.locateCenterOnScreen(
        "scrShot\\StopBattle.png", confidence=0.9, region=searchRegion)
    if findPosCenter:
        logger.info('停战协议还在生效中，不需要再使用。。。')
    else:
        logger.info('停战协议已经失效了，需要使用停战协议道具。。。')
        pyautogui.click(btnStopBattleX, btnStopBattleY, duration=DURATION)

        btnUsedX, btnUsedY = 1221, 477
        pyautogui.click(btnUsedX, btnUsedY, duration=DURATION)

    closeActiveWindows()


def saveCoordinates(CoordinateType='resource'):
    '''# 保存坐标，这样如果有剩余矿可以，继续采集
        # resource---资源矿的坐标
        # rebel camp------ 叛军营地'''
    # 1.首先获取到收藏图标的坐标位置
    searchRegion = (800, 600, 400, 400)
    findPosCenter = pyautogui.locateCenterOnScreen(
        "scrShot\\saveCoordinate.png", confidence=0.9, region=searchRegion)
    if findPosCenter:
        logger.info('定位到收藏图标按钮，保存中。。。')
        pyautogui.click(findPosCenter.x, findPosCenter.y, duration=DURATION)
        btnCreateX, btnCreateY = 840, 823
        pyautogui.click(btnCreateX, btnCreateY, duration=DURATION)
        # 提示有已经有相同的坐标是否覆盖
        searchRegion = (700, 500, 400, 300)
        findPosCenter = pyautogui.locateCenterOnScreen(
            "scrShot\\overwrite.png", confidence=0.9, region=searchRegion)
        if findPosCenter:
            pyautogui.click(findPosCenter.x, findPosCenter.y,
                            duration=DURATION)
    else:
        logger.info('不能定位到收藏图标按钮。。。')


def gatherBookMarkRes(invalidPointList=[]):
    '''
    清除无效的收藏点
    采集收藏夹中的资源点，函数执行一次，删除
    invalidPointList[] 保存无效的收藏资源点
    '''
    # 如果军队数量小于
    armyCount = getArmyCount()
    armyLeft = ARMY_LIMIT - armyCount
    if armyLeft < 1:
        logger.info("已经达到行军队列上限{},不可再派遣军队。".format(ARMY_LIMIT))
        return

    # 点击打开收藏夹
    iconBookMarkX, iconBookMarkY = 1513, 94
    pyautogui.click(iconBookMarkX, iconBookMarkY, duration=DURATION)

    # 点击关注标签页
    tabFollowX, tabFollowY = 1046, 240
    pyautogui.click(tabFollowX, tabFollowY, duration=DURATION)

    # 检查有几个收藏点
    searchRegion = (870, 280, 200, 550)
    findPosList = pyautogui.locateAllOnScreen(
        "scrShot\\followGo.png", confidence=0.9, region=searchRegion)

    # close the window，为了方便后面循环执行关闭窗口，重新打开
    WndBookMarkCloseX, WndBookMarkCloseY = 1083, 192
    pyautogui.click(WndBookMarkCloseX,
                    WndBookMarkCloseY, duration=DURATION)
    # 无效/失效的坐标点
    # invalidPos = []
    cnt = 0
    for pos in findPosList:
        logger.info('逐个检查收藏的资源坐标:x={},y={}'.format(pos.left, pos.top))
        # 打开收藏夹
        pyautogui.click(iconBookMarkX, iconBookMarkY, duration=DURATION)
        pyautogui.click(tabFollowX, tabFollowY, duration=DURATION)

        # 点击前往资源点
        posCenter = pyautogui.center(pos)
        pyautogui.click(posCenter.x, posCenter.y, duration=DURATION)

        # 点击定位的坐标点
        result = gatherResources(SCREEN_MID_X, SCREEN_MID_Y)
        # 派遣成功
        if result == 0:
            cnt += 1
            if cnt >= armyLeft:
                break  # 超过剩余的行军队列数则退出

        # 表明该坐标点已经失效可以清理
        if result < 0:
            invalidPointList.append(posCenter)


def searchSandBox(resType="mine", level=3):
    '''
    使用界面上面的沙盘的搜索功能，搜索相应的资源类型
    参数：
        type: ["mine"铁矿,"mint"铸币厂,"quarry"采石场,"lumberyard"木材厂]
        level: [1-25]
    返回值：
        True 搜索相应的资源成功
        False
    '''
    searchTypePoint = {
        "mine": (481, 414),
        "mint": (481, 281),
        "quarry": (638, 281),
        "farm": (329, 281),
        "lumberyard": (329, 414),
        "rebel": (329, 547)  # 叛军据点
    }
    if resType == "rebel":
        totalLevel = 25
    else:
        totalLevel = 5

    # 其他资源类型都是划分为5级
    # 进度条长度是300 pix， startX=343，startY=750
    searchLevelX = 343 + 300/totalLevel * level
    searchLevelY = 750

    # 打开搜索窗口
    search_x, search_y = 33, 657
    pyautogui.click(search_x, search_y, duration=DURATION)

    # 点击资源类型
    pyautogui.click(*searchTypePoint[resType], duration=DURATION)

    # 点击资源级别
    pyautogui.click(searchLevelX, searchLevelY, duration=DURATION)

    # 开始搜索
    search_btn_x, search_btn_y = 482, 800
    pyautogui.click(search_btn_x, search_btn_y, duration=DURATION)

    # 点击搜索到的资源,搜到的资源会到屏幕的中央
    pyautogui.click(SCREEN_MID_X, SCREEN_MID_Y, duration=DURATION)

    closeActiveWindows()

    return True


def gatherResources(pointX, pointY):
    '''
        在屏幕指定坐标进行资源的采集
    return
        0 采集成功
        1 已经在采集了
        -1 资源点失效
    '''
    # 根据指定的坐标，采集资源
    pyautogui.click(pointX, pointY, duration=DURATION)

    # 判断是不是自己还在采集中。。。出现【回城按钮】表面自己还在采集
    searchRegion = (720, 770, 250, 100)
    findPosCenter = pyautogui.locateCenterOnScreen(
        'scrShot\\backHome.png', confidence=0.9, region=searchRegion)
    if findPosCenter:
        # 关闭窗口
        wndOwnedResCloseX, wndOwnedResCloseY = 1084, 192
        pyautogui.click(wndOwnedResCloseX,
                        wndOwnedResCloseY, duration=DURATION)
        return 1  # 自己已经在采集

    # 校验是否搜索到资源
    findPosCenter = pyautogui.locateCenterOnScreen(
        'scrShot\\gather.png', confidence=0.9, region=searchRegion)
    # 资源还在
    if findPosCenter:
        # 坐标保存起来
        saveCoordinates()
        # 点击采集按钮
        pyautogui.click(findPosCenter.x, findPosCenter.y, duration=DURATION)
        # 按钮 出征
        btnBattleX, btnBattleY = 1149, 802
        pyautogui.click(btnBattleX, btnBattleY, duration=DURATION)

        # 会出现一个行军信息窗口，判断是否派军成功【行军召回按钮】，然后需要关闭
        searchRegion = (690, 880, 400, 100)
        findPosCenter = pyautogui.locateCenterOnScreen(
            'scrShot\\march_back.png', confidence=0.9, region=searchRegion)
        if findPosCenter:
            march_window_x, march_window_y = 1053, 758
            pyautogui.click(march_window_x, march_window_y, duration=DURATION)
            return 0  # 军队派出成功

    # 失效地块
    wndEmptyAreaCloseX, wndEmptyAreaCloseY = 1075, 362
    pyautogui.click(wndEmptyAreaCloseX, wndEmptyAreaCloseY, duration=DURATION)
    return -1


def clearBookMarkInvalidResource(invalidPointList):
    '''清除收藏夹中无效的资源点
    参数：
        invalidPointList [] 无效收藏的坐标
    '''
    # 全部检查完成后，进行统一清理操作
    # 从最后一个无效的开始清理，这样避免删除中间的，会变位置
    # 点击收藏夹
    if not invalidPointList:
        return True

    iconBookMarkX, iconBookMarkY = 1513, 94
    tabFollowX, tabFollowY = 1046, 240

    logger.info('开始清理无效的收藏的资源坐标。。。')
    pyautogui.click(iconBookMarkX, iconBookMarkY, duration=DURATION)
    pyautogui.click(tabFollowX, tabFollowY, duration=DURATION)
    invalidPointList.reverse()
    for pos in invalidPointList:
        # 删除收藏夹中按钮坐标,删除按钮 相对于前往按钮偏移
        offsetX = -111
        btnDelCoordianteX, btnDelCoordianteY = pos.x + offsetX, pos.y
        pyautogui.click(btnDelCoordianteX,
                        btnDelCoordianteY, duration=DURATION)

    # 最后 close the window
    WndBookMarkCloseX, WndBookMarkCloseY = 1083, 192
    pyautogui.click(WndBookMarkCloseX,
                    WndBookMarkCloseY, duration=DURATION)


def gatherAndClearFromBookmark():
    pl = []
    gatherBookMarkRes(pl)
    clearBookMarkInvalidResource(pl)


def KingVsKing():
    """KVK战争模式下特殊的处理"""
    # 检查保护罩是否开启
    # 检查宝箱
    # 检查 酒馆奖励
    # 联盟帮助
    # 怎么优先采金矿
    switchMapMode("country")
    stopBattle()
    checkChest()
    checkQuest()
    checkHospital()

    switchMapMode("world")
    gatherForKvK(2)

    # 国战期间，时间设置短些
    logger.info("本次任务执行结束，下次任务3分钟后开启。")
    Timer(180, KingVsKing).start()


def gatherForKvK(level=2):
    # 搜索资源矿,然后派兵采集
    # Mine LV3:37K LV4:71K 铁矿
    # Mint LV3:19K LV4:32K 铸币厂
    # Quarry LV3:53K LV4:90K  采石场
    # Lumberyard LV3:53K LV4:90K  木材厂
    turn = ["iron",  "mint"]
    # level=3 默认采矿级别3级

    switchMapMode("world")

    # 搜索按钮
    search_x, search_y = 33, 657
    search_stone_x, search_stone_y = 638, 281
    search_mint_x,  search_mint_y = 481, 281
    search_farm_x,  search_farm_y = 329, 281
    search_wood_x,  search_wood_y = 329, 414
    search_iron_x,  search_iron_y = 481, 414
    search_level2_x, search_level2_y = 460, 752
    search_level3_x, search_level3_y = 541, 752

    search_btn_x, search_btn_y = 482, 800

    if level == 1:
        search_level_x, search_level_y = search_level2_x, search_level2_y
    elif level == 2:
        search_level_x, search_level_y = search_level2_x, search_level2_y
    elif level == 3:
        search_level_x, search_level_y = search_level3_x, search_level3_y
    elif level == 4:
        search_level_x, search_level_y = search_level3_x, search_level3_y
    elif level == 5:
        search_level_x, search_level_y = search_level3_x, search_level3_y
    else:
        search_level_x, search_level_y = search_level3_x, search_level3_y

    # 如果军队数量小于
    armyCount = getArmyCount()
    armyLeft = ARMY_LIMIT - armyCount
    logger.info("KVK 还可以派遣{}支军队去采集资源。".format(armyLeft))
    for i in range(armyLeft):
        # 打开搜索窗口
        pyautogui.click(search_x, search_y)

        # 随机一个矿产资源
        mineType = random.choice(turn)
        if mineType == "iron":
            search_resource_x, search_resource_y = search_iron_x, search_iron_y
        elif mineType == "stone":
            search_resource_x, search_resource_y = search_stone_x, search_stone_y
        elif mineType == "mint":
            search_resource_x, search_resource_y = search_mint_x, search_mint_y
        elif mineType == "wood":
            search_resource_x, search_resource_y = search_wood_x, search_wood_y
        elif mineType == "farm":
            search_resource_x, search_resource_y = search_farm_x, search_farm_y
        else:
            return

        pyautogui.click(search_resource_x,
                        search_resource_y, duration=DURATION)

        # 点击资源级别
        pyautogui.click(search_level_x, search_level_y, duration=DURATION)

        # 开始搜索
        pyautogui.click(search_btn_x, search_btn_y, duration=DURATION)

        # 点击搜索到的资源,搜到的资源会到屏幕的中央
        result = gatherResources(SCREEN_MID_X, SCREEN_MID_Y)

        if result:
            notes = "KVK 已经派出了{0}支军队，现在派出第{1}支军队去采集资源矿{2}".format(
                armyCount + i, (armyCount + i + 1), mineType)
            logger.info(notes)


def claimResourceAutoRand():
    """自动采集矿厂资源，随机选择矿厂
    # Mine 铁矿
    # Mint 铸币厂
    # Quarry 采石场
    # Lumberyard 木材厂
    """

    turn = ["mine",  "quarry", "lumberyard"]
    level = 3  # 默认采矿级别3级

    switchMapMode("world")

    # 如果军队数量小于
    armyCount = getArmyCount()
    armyLeft = ARMY_LIMIT - armyCount
    if armyLeft < 1:
        logger.info("已经达到行军队列上限{}，不可以再派遣军队去采集资源。".format(ARMY_LIMIT))
        return
    else:
        logger.info("还可以派遣{}支军队去采集资源。".format(armyLeft))

    for i in range(armyLeft):

        # 随机一个矿产资源
        resType = random.choice(turn)

        # 开始搜索
        searchSandBox(resType, level)

        # 点击搜索到的资源,搜到的资源会到屏幕的中央
        result = gatherResources(SCREEN_MID_X, SCREEN_MID_Y)

        if result == 0:
            notes = "采集资源：{0} 级别：{1}，现在派出第{2}支军队。".format(
                resType, level, (armyCount + i + 1))
            logger.info(notes)
            return
        elif result == 1:
            notes = "采集资源：{0} 级别：{1}，派遣失败，原因：已经有人采集中。".format(
                resType, level)
            logger.info(notes)
        else:
            notes = "采集资源：{0} 级别：{1}，派遣失败，原因未知。".format(
                resType, level)
            logger.info(notes)

        closeActiveWindows()


def searchCoordinates(crdnatesX, crdnatesY):
    """根据用户输入坐标搜索转到地图对应位置"""
    logger.info("搜索地图坐标X:{} Y:{}".format(crdnatesX, crdnatesY))
    searchBtnX, searchBtnY = 1653, 286
    # btnCloseX, btnCloseY=1073,361
    btnGoThereX, btnGoThereY = 963, 655
    # 地图坐标Y输入框位置
    CoordnateXInputX, CoordnateXInputY = 882, 505
    # 地图坐标X输入框位置
    CoordnateYInputX, CoordnateYInputY = 1028, 505

    # 打开坐标搜索框
    pyautogui.click(searchBtnX, searchBtnY, duration=DURATION)

    # 输入X坐标
    pyautogui.click(CoordnateXInputX, CoordnateXInputY, duration=DURATION)
    pyautogui.hotkey("ctrl", "A")
    pyautogui.write(str(crdnatesX))

    # 输入Y坐标
    pyautogui.click(CoordnateYInputX, CoordnateYInputY, duration=DURATION)
    pyautogui.hotkey("ctrl", "A")
    pyautogui.write(str(crdnatesY))

    # 前往查找
    pyautogui.click(btnGoThereX, btnGoThereY, duration=DURATION)

    # test debug
    pyautogui.click(SCREEN_MID_X, SCREEN_MID_Y, duration=DURATION)
    closeActiveWindows()
    # pyautogui.click(btnCloseX, btnCloseY, duration=DURATION)


def changeEquipment(setMode="B"):
    """
    自动更换装备，Buff加速，方便研发加速
    参数：
        setMode: 
            B  建筑加速的装备
            R  研发加速的装备
            T  训练加速的装备
            G  采集加速装备

    """
    headImageX, headImageY = 64, 140

    # 增加研发速度 学士套装系列
    masterSet = {
        "head": "MasterHood",
        "main-hand": "MasterQuill",
        "legs": "MasterShoes",
        "off-hand": "HuntsmanQuiver",
        "chest": "MasterRobes",
        "accessory": ["KrakenPendant", "SevenPointStarPendant", "EyeofRhllor"]
    }

    # 增加建设速度
    BuilderSet = {
        "head": "BuilderHood",
        "main-hand": "BuilderPickaxe",
        "legs": "BuilderTrousers",
        "off-hand": "BuilderHammer",
        "chest": "BuilderArmor",
        "accessory": ["BlackGoatTalisman", "BoneNecklace", "HeartoftheOcean"]
    }

    # 资源采集速度
    hunterSet = {
        "head": "HuntsmanHood",
        "main-hand": "HuntsmanSkinningKnife",
        "legs": "HuntsmanTrousers",
        "off-hand": "HuntsmanQuiver",
        "chest": "NewLordArmor",
        "accessory": ["", "", ""]
    }

    pyautogui.click(headImageX, headImageY, duration=DURATION)

    lordSets = {"B": BuilderSet, "R": masterSet, "G": hunterSet}
    lordSetName = {"B": "建筑加速相关装备", "R": "研发加速相关装备", "G": "采集加速相关装备"}
    lordSet = lordSets[setMode]

    logger.info("开始更换装备：{}".format(lordSetName[setMode]))

    for name, equipName in lordSet.items():
        if name == "accessory":
            changePartEquipment("accessory1", equipName[0])
            changePartEquipment("accessory2", equipName[1])
            changePartEquipment("accessory3", equipName[2])
        else:
            changePartEquipment(name, equipName)

    logger.info("结束更换装备：{}".format(lordSetName[setMode]))


def changePartEquipment(partName, equipName):
    HeadX, HeadY = 771, 355
    mainHandX, mainHandY = 790, 496
    legsX, LegsY = 772, 652
    offHandX, offHandY = 772, 755
    chestX, chestY = 1260, 500
    accessory1X, accessory1Y = 1281, 352
    accessory2X, accessory2Y = 1281, 656
    accessory3X, accessory3Y = 1281, 754
    btnChangeX, btnChangeY = 1182, 811

    # 替换的装备未设置则跳过
    if not equipName:
        logger.info("替换当前身体部位：{}的装备为空，忽略跳过。".format(partName))
        # 关闭当前窗口
        pyautogui.click(1342, 189, duration=DURATION)
        return

    lordBodyPart = {
        "head": (HeadX, HeadY),
        "main-hand": (mainHandX, mainHandY),
        "legs": (legsX, LegsY),
        "off-hand": (offHandX, offHandY),
        "chest": (chestX, chestY),
        "accessory1": (accessory1X, accessory1Y),
        "accessory2": (accessory2X, accessory2Y),
        "accessory3": (accessory3X, accessory3Y)
    }

    pyautogui.click(*lordBodyPart[partName])
    pyautogui.click(btnChangeX, btnChangeY, duration=DURATION)

    if partName == "accessory1" or partName == "accessory2" or partName == "accessory3":
        dirName = "accessory"
    else:
        dirName = partName

    searchRegion = (330, 210, 550, 650)
    logger.info("开始替换当前身体部位：{}的装备为：{}".format(partName, equipName))
    findPos = pyautogui.locateCenterOnScreen("equipment\\{}\\{}.png".format(
        dirName, equipName), confidence=0.9, region=searchRegion)
    if findPos:
        pyautogui.click(findPos.x, findPos.y, duration=DURATION)
        searchRegion = (920, 775, 400, 80)
        findPos = pyautogui.locateCenterOnScreen(
            "equipment\\buttonReplace.png", confidence=0.9, region=searchRegion)
        if findPos:
            pyautogui.click(findPos.x, findPos.y, duration=DURATION)
            logger.info("【成功】替换当前身体部位：{}的装备为：{}".format(partName, equipName))
        else:
            logger.info("已经是当前装备不需要替换。")

    else:
        logger.warning("【失败】替换当前身体部位：{}的装备为：{}".format(partName, equipName))
        # raise Exception("未找到对应的装备，请核实。")

    # 关闭当前窗口
    pyautogui.click(1342, 189, duration=DURATION)


if __name__ == "__main__":
    # 保持主屏幕获得焦点
    setWndFocus()
    fire.Fire({
        "ch": changeEquipment,
        "claim":claimResourceAutoRand,
        "do": doTimerMinutes})
